feat(run): add watch-mode keyboard shortcuts#38
Open
bgelatti wants to merge 3 commits into
Open
Conversation
Adds a parent-side keystroke layer (q/h/?/r/c plus double-Ctrl-C force-quit) on top of tsx/deno/tsnd's existing file watcher, plus a --no-interactive opt-out and a TTY guard so CI and piped runs stay unchanged. The respawn loop owns the child lifecycle with `exec` and `stdio: ["ignore", ...]` so signals reach the analysis runtime cleanly and keystrokes never leak to the child as phantom restarts.
The spawned command interpolated scriptPath unquoted, so a project path containing a space was split into two shell arguments and the runtime failed to find the file. Wrap the path in quotes and add a regression test covering a spaced analysisPath.
Collaborator
|
Ran the watch-mode shortcuts end-to-end against a real analysis on a TTY. Verified each path covered by this PR:
The two latent spawn bugs (the Also re-verified the path-quoting fix (#38) with a project path containing a space — the analysis launches correctly now. |
mateuscardosodeveloper
approved these changes
Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
While
tagoio run <analysis>was active, the user had no way to interact with the running process beyond Ctrl-C. There was no manual restart, no way to clear the screen between runs, no in-session help, and no escape hatch for a hung cleanup. The dev loop felt worse than every comparable tool (vitest, nodemon, wrangler dev).Investigation
readline.emitKeypressEvents+process.stdin.setRawMode. The dedicated npm packages (keypress,ink,terminal-kit,blessed) are all either unmaintained, full TUI frameworks with 25+ transitive deps, or prompt libraries that do not support background listening. Rolling our own on the Node primitives is the proven path — no new dependencies.shell: truemeantkill()only killed the wrapper shell, leaving the tsx/deno/tsnd runtime running as a zombie that kept printing (looked like a phantom restart on every key); 2)stdio: "inherit"let keystrokes leak from the parent's terminal into the child, which tsx then interpreted as its own watch-mode rerun trigger.Solution
A thin parent-side keystroke layer that owns the child lifecycle:
q(quit),h/?(help),r(restart, full re-spawn),c(clear screen). First Ctrl-C is a graceful quit; a second Ctrl-C within 2s force-exits with code 130.--no-interactiveflag opts out (CI, piped logs, Docker). Non-TTY runs are unchanged from before.execprefix on the spawned command so killing the child PID actually kills the analysis runtime, not just the wrapper shell. Child stdin is set toignorewhile shortcuts are active, so keys cannot leak through to tsx.src/lib/watch-shortcuts.tson native Node APIs; zero new dependencies.run-analysis.tsis refactored into a respawn loop driven by the shortcut handlers, with cleanup (run_on: "tago") infinallyso it fires on every exit path.Tests
run-analysiscovering restart re-spawn, quit cleanup,--no-interactiveskip, and non-TTY skip.Note for reviewers
Branched off
feat/entity-commands(branch-from-a-branch). PR is targeted there so the diff is scoped strictly to the watch-shortcuts work — review against `feat/entity-commands`, not `master`.